package edu.neu.cs6515.player.strategy;

import java.util.List;
import java.util.Map.Entry;

import edu.neu.cs6515.admin.Administrator;
import edu.neu.cs6515.board.BoardCoord;
import edu.neu.cs6515.board.HexagonBoard;
import edu.neu.cs6515.util.Pair;
import edu.neu.cs6515.xml.IngeniousColor;
import edu.neu.cs6515.xml.Placement;
import edu.neu.cs6515.xml.Score;
import edu.neu.cs6515.xml.Tile;

/**
 * This strategy seek placement that can increase points for lower scored
 * colors.
 */
public class LowerColorsMorePointsStrategy extends AbstractStrategy {

    @Override
    public Placement getNextMove(final List<Tile> tilesInHand,
            final int numberOfPlayers,
            final List<Placement> placementsSofar,
            final Score scoreBeforePlacement) {
        HexagonBoard hexBoard = new HexagonBoard(numberOfPlayers);
        List<Pair<BoardCoord>> possibleBoardCoords =
                getAllPossiblePlacements(placementsSofar,
                        hexBoard);

        int maxWeightedSum = 0;
        Placement bestPlacement = createPlacement(possibleBoardCoords.get(0),
                tilesInHand.get(0));

        for (Pair<BoardCoord> pair : possibleBoardCoords) {
            for (Tile tile : tilesInHand) {
                Placement p = createPlacement(pair, tile);
                int weightedSum = getWeightedSumForPlacement(hexBoard, p, scoreBeforePlacement);

                if (maxWeightedSum < weightedSum) {
                    maxWeightedSum = weightedSum;
                    bestPlacement = p;
                }
            }
        }
        return bestPlacement;
    }

    /**
     * @param hexBoard
     *            board for the placement
     * @param p
     *            placement
     * @param scoreBeforePlacement
     *            score for the board
     * @return weight for the placement on the hexBoard based on
     *         scoreBeforePlacement
     */
    protected int getWeightedSumForPlacement(final HexagonBoard hexBoard,
            final Placement p, final Score scoreBeforePlacement) {
        Score scoreOfPlacement = hexBoard.scoreAMove(p);
        List<Entry<IngeniousColor, Integer>> sortedColors =
                scoreBeforePlacement.getIncreasingOrderSortedScore();

        int weightedSum = 0;
        int lastLowestPoints = sortedColors.get(0).getValue();
        int weight = sortedColors.size();
        for (Entry<IngeniousColor, Integer> entry : sortedColors) {
            int points = entry.getValue();
            if (lastLowestPoints < points) {
                weight--;
            }
            weightedSum += scoreOfPlacement.getPointsForColor(entry.getKey()) * weight;
        }
        return weightedSum;
    }

}
